package org.example.server.goods.repo;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import org.example.api.goods.goods.request.AddGoodsRequest;
import org.example.api.goods.goods.request.DeleteGoodsRequest;
import org.example.api.goods.goods.request.GoodsSearchRequest;
import org.example.frw.api.base.intf.ID;
import org.example.frw.api.base.intf.impl.IDPojo;
import org.example.server.goods.entity.*;
import org.example.server.goods.mapper.*;
import org.example.server.goods.mapstruct.category.CategoryConverter;
import org.example.server.goods.mapstruct.goods.GoodsConverter;
import org.example.server.goods.mapstruct.goods.param.ParamConverter;
import org.example.server.goods.mapstruct.goods.sku.SkuConverter;
import org.example.server.goods.mapstruct.goods.tag.TagConverter;
import org.example.server.goods.repo.doo.CategorySummaryDo;
import org.example.server.goods.repo.doo.GoodsFatDetailDo;
import org.example.server.goods.repo.doo.GoodsListItemDo;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class GoodsDbRepo implements GoodsRepoInterface{
  @Resource
  private GoodsMapper goodsMapper;
  @Resource
  private GoodsImageMapper goodsImageMapper;
  @Resource
  private CategoryConverter categoryConverter;
  @Resource
  private GoodsParamMapper goodsParamMapper;
  @Resource
  private GoodsDetailMapper goodsDetailMapper;
  @Resource
  private GoodsConverter goodsConverter;
  @Resource
  private SkuConverter skuConverter;
  @Resource
  private TagConverter tagConverter;
  @Resource
  private ParamConverter paramConverter;
  @Resource
  private GoodsSkuMapper goodsSkuMapper;
  @Resource
  private GoodsTagMapper goodsTagMapper;
  @Resource
  private CategoryMapper categoryMapper;

  private static LambdaQueryWrapper<GoodsEntity> getGoodsEntityLambdaQueryWrapper(GoodsSearchRequest request) {
    return new LambdaQueryWrapper<GoodsEntity>()
            .eq(request.getCategoryId() != null, GoodsEntity::getCategoryId, request.getCategoryId());
  }

  @Override
  public List<GoodsListItemDo> pageGoods(GoodsSearchRequest request) {
    // 分页查询商品
    LambdaQueryWrapper<GoodsEntity> queryWrapper = getGoodsEntityLambdaQueryWrapper(request);
    Page<GoodsEntity> goodsEntityPage = goodsMapper.selectPage(new Page<>(request.getPage().current(), request.getPage().getPageSize()), queryWrapper);
    if(CollUtil.isEmpty(goodsEntityPage.getRecords())){
      return new ArrayList<>();
    }
    // 根据goodsEntityPage的categoryId批量查询path
    List<Long> categoryIds = goodsEntityPage.getRecords().stream().map(GoodsEntity::getCategoryId).distinct().toList();
    List<CategoryEntity> categoryEntities = categoryMapper.selectBatchIds(categoryIds);
    Map<Long, CategoryEntity> categoryEntitiesMap = categoryEntities.stream().collect(Collectors.toMap(CategoryEntity::getId, categoryEntity -> categoryEntity));


    return goodsEntityPage.getRecords().stream().map(goodsEntity -> {
      GoodsListItemDo goodsListItemDo = goodsConverter.toGoodsListItemDo(goodsEntity);
      CategoryEntity categoryEntity = categoryEntitiesMap.get(goodsEntity.getCategoryId());
      if(categoryEntity != null){
        goodsListItemDo.setCategoryPath(categoryEntity.getPath());
      }
      return goodsListItemDo;
    }).toList();
  }

  @Override
  public Long goodsCount(GoodsSearchRequest request) {
    return goodsMapper.selectCount(getGoodsEntityLambdaQueryWrapper(request));
  }

  @Override
  public void deleteGoods(DeleteGoodsRequest request) {
    goodsMapper.deleteById(request.getId());
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public ID addGoods(AddGoodsRequest request) {
    // 存储基本信息
    GoodsEntity goodsEntity = goodsConverter.toGoodsEntity(request.getBaseInfo(),request.getPriceInfo().getSalesType());
    goodsMapper.insert(goodsEntity);

    final Long goodsId = goodsEntity.getId();

    // 存储轮播图
    List<GoodsImageEntity> goodsImageEntities = new ArrayList<>();
    request.getBaseInfo().getCarouselImage().forEach(image -> {
      GoodsImageEntity goodsImageEntity = new GoodsImageEntity();
      goodsImageEntity.setGoodsId(goodsId);
      goodsImageEntity.setImage(image);
      goodsImageEntities.add(goodsImageEntity);
    });
    goodsImageMapper.insertBatchSomeColumn(goodsImageEntities);

    // 存储sku信息
    AddGoodsRequest.PriceInfoRequest priceInfo = request.getPriceInfo();
    List<GoodsSkuEntity> skus = priceInfo.getSkus().stream().map(sku -> skuConverter.toGoodsSkuEntity(sku,goodsId)).collect(Collectors.toList());
    goodsSkuMapper.insertBatchSomeColumn(skus);

    // 存储tag
    List<GoodsTagEntity> tagEntities = request.getParamsInfo().getTags().stream().map(tag -> {
      GoodsTagEntity goodsTagEntity = new GoodsTagEntity();
      goodsTagEntity.setGoodsId(goodsId);
      goodsTagEntity.setName(tag.name());
      goodsTagEntity.setType(tag.getType());
      return goodsTagEntity;
    }).collect(Collectors.toList());
    if(CollUtil.isNotEmpty(tagEntities)){
      goodsTagMapper.insertBatchSomeColumn(tagEntities);
    }

    // 存储param
    List<GoodsParamEntity> paramEntities = request.getParamsInfo().getParams().stream().map(param -> {
      GoodsParamEntity goodsParamEntity = new GoodsParamEntity();
      goodsParamEntity.setGoodsId(goodsId);
      goodsParamEntity.setName(param.getName());
      goodsParamEntity.setDescription(param.getDescription());
      return goodsParamEntity;
    }).collect(Collectors.toList());
    goodsParamMapper.insertBatchSomeColumn(paramEntities);

    // 存储商品详情
    if(request.getDetailInfo() != null){
      GoodsDetailEntity goodsDetailEntity = new GoodsDetailEntity();
      goodsDetailEntity.setGoodsId(goodsId);
      goodsDetailEntity.setHtml(request.getDetailInfo().getHtml());
      goodsDetailMapper.insert(goodsDetailEntity);
    }

    return new IDPojo(goodsId);
  }

  @Override
  public GoodsFatDetailDo fatDetail(Long id) {
    GoodsEntity goodsEntity = goodsMapper.selectById(id);
    if(goodsEntity == null){
      return null;
    }
    GoodsFatDetailDo goodsFatDetailDo = new GoodsFatDetailDo();
    goodsFatDetailDo.setTitle(goodsEntity.getTitle());
    goodsFatDetailDo.setSubTitle(goodsEntity.getSubTitle());
    goodsFatDetailDo.setStatus(goodsEntity.getStatus().getCode());
    goodsFatDetailDo.setCreateTime(goodsEntity.getCreateTime());
    goodsFatDetailDo.setUpdateTime(goodsEntity.getUpdateTime());
    goodsFatDetailDo.setId(goodsEntity.getId());
    // sku
    List<GoodsSkuEntity> skuEntities = goodsSkuMapper.selectList(new LambdaQueryWrapper<GoodsSkuEntity>().eq(GoodsSkuEntity::getGoodsId, id));
    // params
    List<GoodsParamEntity> paramEntities = goodsParamMapper.selectList(new LambdaQueryWrapper<GoodsParamEntity>().eq(GoodsParamEntity::getGoodsId, id));
    // tags
    List<GoodsTagEntity> tagEntities = goodsTagMapper.selectList(new LambdaQueryWrapper<GoodsTagEntity>().eq(GoodsTagEntity::getGoodsId, id));
    // category
    CategoryEntity categoryEntity = categoryMapper.selectOne(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getId, goodsEntity.getCategoryId()));

    CategorySummaryDo categorySummaryDo = categoryConverter.toCategorySummaryFromEntity(categoryEntity);
    goodsFatDetailDo.setCategory(categorySummaryDo);
    goodsFatDetailDo.setSkus(skuConverter.toGoodsSkuDoFromEntity(skuEntities));
    goodsFatDetailDo.setTags(tagConverter.toTagDoFromEntity(tagEntities));
    goodsFatDetailDo.setParams(paramConverter.toParamDoFromEntity(paramEntities));

    return goodsFatDetailDo;
  }

}
